package com.example.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.common.PageResult;
import com.example.common.Result;
import com.example.dto.SpuDto;
import com.example.entity.*;
import com.example.service.*;
import com.example.utils.JwtUtil;
import com.example.vo.SSpuVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.*;

@RestController
@RequestMapping("/goods")
@Slf4j
@Api(tags = "商品相关接口", value = "商品相关接口")
public class SSpuController {

    @Autowired
    private SSpuService spuService;
    @Autowired
    private SSkuService skuService;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private UserService userService;
    @Autowired
    private SCategoryService sCategoryService;
    @Autowired
    private SBrandService brandService;

    public User getUser() {
        String token = request.getHeader("Authorization");
        String username = JwtUtil.getUsername(token);
        return userService.getOne(Wrappers.<User>lambdaQuery().eq(User::getUsername, username));
    }



    @ApiOperation("后台新增商品大类")
    @PostMapping("/spu")
    public Result<?> generalSave(@RequestBody SpuDto spuDto) {
        //根据种类表新增该种类的大类，获取对应category_id
        LambdaQueryWrapper<SCategory> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(SCategory::getName, spuDto.getCategoryName());
        spuDto.setCategoryId(sCategoryService.getOne(wrapper1).getId());
        //根据品牌表新增该品牌的大类，获取对应brand_id
        LambdaQueryWrapper<SBrand> Wrapper2 = new LambdaQueryWrapper<>();
        Wrapper2.eq(SBrand::getName, spuDto.getBrandName());
        spuDto.setBrandId(brandService.getOne(Wrapper2).getId());
        spuService.save(spuDto);
        return Result.success();
    }



    @ApiOperation("根据spu_id批量删除商品大类")
    @DeleteMapping("/spuDelete")
    public Result<?> deleteSpu(@RequestBody List<Long> list) throws Exception {
        spuService.removeBatchByIds(list);
        LambdaQueryWrapper<SSku> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SSku::getSpuId,list);
        skuService.remove(wrapper);
        return Result.success();
    }





    @ApiOperation("更新Spu信息外加品牌名，种类")
    @PutMapping("/spu")
    public Result<?> updateSpu(@RequestBody SpuDto spuDto){
        //先更新spu有的属性
        LambdaQueryWrapper<SSpu> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SSpu::getId, spuDto.getId());
        SSpu sSpu = new SSpu();
        sSpu.setName(spuDto.getName());
        sSpu.setAttribute(spuDto.getAttribute());
        sSpu.setPrice(spuDto.getPrice());
        //修改该spu下所有sku的标价
        LambdaUpdateWrapper<SSku> updateWrapper = new LambdaUpdateWrapper<SSku>()
                .eq(SSku::getSpuId, spuDto.getId())
                .set(SSku::getPrice, spuDto.getPrice());
        skuService.update(updateWrapper);
        sSpu.setUrls(spuDto.getUrls());
        sSpu.setDetail(spuDto.getDetail());
        sSpu.setUpdateTime(LocalDateTime.now());

        //修改spu的categoryId根据categoryName查询id
        LambdaQueryWrapper<SCategory> wrapper1 =new LambdaQueryWrapper<>();
        wrapper1.eq(SCategory::getName,spuDto.getCategoryName());
        SCategory one = sCategoryService.getOne(wrapper1);
        sSpu.setCategoryId(one.getId());
        //修改spu的brandId根据brandName查询id
        LambdaQueryWrapper<SBrand> wrapper2 =new LambdaQueryWrapper<>();
        wrapper2.eq(SBrand::getName,spuDto.getBrandName());
        SBrand two = brandService.getOne(wrapper2);
        sSpu.setBrandId(two.getId());
        spuService.update(sSpu,wrapper);
        return Result.success();
    }


    /**
     * 根据spu_id获取颜色
     */
    @ApiOperation("根据spu_id获取颜色列表")
    @GetMapping("/colorByid")
    public Result<List> findColor(@RequestParam Long id){
        SSpuVO vo = new SSpuVO();
        LambdaQueryWrapper<SSku> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(SSku::getAttribute).eq(SSku::getSpuId,id);
        List<Map<String, Object>> list = skuService.listMaps(wrapper);
        List<String> colorlist = new ArrayList<>();
        for (Map map:
                list) {
            //{attribute={"size": "40码", "color": "蓝色"}}
            Collection values = map.values();
            Iterator iter = values.iterator();
            while (iter.hasNext()){
                //{"size": "40码", "color": "绿色"}
                Object obj=iter.next();
                //将对象转为JsonString
                String s = obj.toString();
                //使用JSON解析库将JsonString转为map
                JSONObject jsonObject = new JSONObject(s);
                Map<String, Object> map1 = jsonObject.toMap();
                //获取color或size
                Object o = map1.get("color");
                colorlist.add(o.toString());
            }
        }
        //将 List 转换为 Set，因为 Set 不允许重复元素，然后再将 Set 转换回 List。
        Set<String> set = new LinkedHashSet<>(colorlist);
        // 使用 LinkedHashSet 保持原始顺序
        colorlist.clear();
        colorlist.addAll(set);
        vo.setColorList(colorlist);
        return Result.success(vo.getColorList());

    }



    /**
     * 根据spu_id获取尺码
     */
    @ApiOperation("根据spu_id获取尺码列表")
    @GetMapping("/sizeByid")
    public Result<List> findSizeByid(@RequestParam Long id){
        SSpuVO vo = new SSpuVO();
        LambdaQueryWrapper<SSku> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(SSku::getAttribute).eq(SSku::getSpuId,id);
        List<Map<String, Object>> list = skuService.listMaps(wrapper);
        List<String> sizelist = new ArrayList<>();
        for (Map map:
                list) {
            //{attribute={"size": "40码", "color": "蓝色"}}
            Collection values = map.values();
            Iterator iter = values.iterator();
            while (iter.hasNext()){
                //{"size": "40码", "color": "绿色"}
                Object obj=iter.next();
                //将对象转为JsonString
                String s = obj.toString();
                //使用JSON解析库将JsonString转为map
                JSONObject jsonObject = new JSONObject(s);
                Map<String, Object> map1 = jsonObject.toMap();
                //获取color或size
                Object o = map1.get("size");
                sizelist.add(o.toString());
            }
        }
        //将 List 转换为 Set，因为 Set 不允许重复元素，然后再将 Set 转换回 List。
        Set<String> set = new LinkedHashSet<>(sizelist);
        // 使用 LinkedHashSet 保持原始顺序
        sizelist.clear();
        sizelist.addAll(set);
        vo.setSizeList(sizelist);
        return Result.success(vo.getSizeList());
    }
    /**
     * 根据spu_id和尺码获取颜色
     */
    @ApiOperation("根据spu_id和尺码获取颜色")
    @GetMapping("/colorBySize")
    public Result<List> findColorBySize(@RequestParam Long id,@RequestParam String size){
        SSpuVO vo = new SSpuVO();
        LambdaQueryWrapper<SSku> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(SSku::getAttribute).eq(SSku::getSpuId,id);
        List<Map<String, Object>> list = skuService.listMaps(wrapper);
        List<String> colorlist = new ArrayList<>();
        for (Map map:
                list) {
            //{attribute={"size": "40码", "color": "蓝色"}}
            Collection values = map.values();
            Iterator iter = values.iterator();
            while (iter.hasNext()){
                //{"size": "40码", "color": "绿色"}
                Object obj=iter.next();
                //将对象转为JsonString
                String s = obj.toString();
                //使用JSON解析库将JsonString转为map
                JSONObject jsonObject = new JSONObject(s);
                Map<String, Object> map1 = jsonObject.toMap();
                //获取color或size
                if(map1.get("size").toString().equals(size)){
                    Object o = map1.get("color");
                    colorlist.add(o.toString());
                }
            }
        }
        //将 List 转换为 Set，因为 Set 不允许重复元素，然后再将 Set 转换回 List。
        Set<String> set = new LinkedHashSet<>(colorlist);
        // 使用 LinkedHashSet 保持原始顺序
        colorlist.clear();
        colorlist.addAll(set);
        vo.setSizeList(colorlist);
        return  Result.success(colorlist);
    }


    /**
     * 根据spu_id和颜色获取尺码
     */
    @ApiOperation("根据spu_id和颜色获取尺码")
    @GetMapping("/sizeByColor")
    public Result<List> findSizeByColor(@RequestParam Long id,@RequestParam String color){
        SSpuVO vo = new SSpuVO();
        LambdaQueryWrapper<SSku> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(SSku::getAttribute).eq(SSku::getSpuId,id);
        List<Map<String, Object>> list = skuService.listMaps(wrapper);
        List<String> sizelist = new ArrayList<>();
        for (Map map:
                list) {
            //{attribute={"size": "40码", "color": "蓝色"}}
            Collection values = map.values();
            Iterator iter = values.iterator();
            while (iter.hasNext()){
                //{"size": "40码", "color": "绿色"}
                Object obj=iter.next();
                //将对象转为JsonString
                String s = obj.toString();
                //使用JSON解析库将JsonString转为map
                JSONObject jsonObject = new JSONObject(s);
                Map<String, Object> map1 = jsonObject.toMap();
                //获取color或size
                if(map1.get("color").toString().equals(color)){
                    Object o = map1.get("size");
                    sizelist.add(o.toString());
                }
            }
        }
        //将 List 转换为 Set，因为 Set 不允许重复元素，然后再将 Set 转换回 List。
        Set<String> set = new LinkedHashSet<>(sizelist);
        // 使用 LinkedHashSet 保持原始顺序
        sizelist.clear();
        sizelist.addAll(set);
        vo.setSizeList(sizelist);
        return  Result.success(sizelist);
    }

//商品查询后台


    /**
     * 推荐商品
     *
     * @return
     */
    @ApiOperation("前台获取推荐商品")
    @GetMapping("/recommend")
    public Result<?> recommend() {
        List<SSpuVO> list = spuService.recommend();
        return Result.success(list);
    }


    /**
     * 推热销商品
     *
     * @return
     */
    @ApiOperation("前台获取热销商品")
    @GetMapping("/sales")
    public Result<?> sales() {
        List<SSpuVO> list = spuService.sales();
        return Result.success(list);
    }



//    @PostMapping("/findAllByCondition")
//    @ApiOperation("根据商品名字/品牌/种类模糊搜索商品大类")
//    public Result<PageResult<SSpuVO>> findPage(@RequestBody(required = false) SpuDto spuDto,
//                                             @RequestParam(required = false,defaultValue = "1") Integer pageNum,
//                                             @RequestParam(required = false,defaultValue = "5") Integer pageSize) {
//
//        IPage<SSpuVO> page = spuService.findPage(new Page<>(pageNum, pageSize),spuDto);
//        PageResult<SSpuVO> pageResult = PageResult
//                .<SSpuVO>builder()
//                .current(page.getCurrent())
//                .size(page.getSize())
//                .total(page.getTotal())
//                .records(page.getRecords())
//                .build();
//
//        return Result.success(pageResult);
//    }

    @ApiOperation("后台根据商品名字/品牌/种类/销量、价格升/降序模糊搜索商品大类")
    @PostMapping("/findAllByCondition")
    public Result<PageResult<SSpuVO>> findpageBySalesOrPrice(@RequestBody(required = false) SpuDto spuDto,
                                                             @RequestParam(required = false,defaultValue = "0") Integer sortType,
                                                             @RequestParam(required = false,defaultValue = "1") Integer pageNum,
                                                             @RequestParam(required = false,defaultValue = "5") Integer pageSize){
        IPage<SSpuVO> page = null;
        //sortType：1 销量升序，2销量降序，3价格升序，4价格降序
        switch (sortType){
            case 0:
                page = spuService.findPage(new Page<>(pageNum, pageSize),spuDto);
                break;
            case 1:
                page = spuService.findPageBySalesAsc(new Page<>(pageNum, pageSize),spuDto);
                break;
            case 2:
                page = spuService.findPageBySalesDesc(new Page<>(pageNum, pageSize),spuDto);
                break;
            case 3:
                page = spuService.findPageByPriceAsc(new Page<>(pageNum, pageSize),spuDto);
                break;
            case 4:
                page = spuService.findPageByPriceDesc(new Page<>(pageNum, pageSize),spuDto);
                break;
        }
        PageResult<SSpuVO> pageResult = PageResult
                .<SSpuVO>builder()
                .current(page.getCurrent())
                .size(page.getSize())
                .total(page.getTotal())
                .records(page.getRecords())
                .build();

        return Result.success(pageResult);

    }


    @ApiOperation("前台根据商品名字/品牌/种类/销量、价格升/降序模糊搜索商品大类")
    @PostMapping("/frontFindAll")
    public Result<PageResult<SSpuVO>> FrontFindpageBySalesOrPrice(@RequestBody(required = false) SpuDto spuDto,
                                                             @RequestParam(required = false,defaultValue = "0") Integer sortType,
                                                             @RequestParam(required = false,defaultValue = "1") Integer pageNum,
                                                             @RequestParam(required = false,defaultValue = "5") Integer pageSize){
        IPage<SSpuVO> page = null;
        //sortType：1 销量升序，2销量降序，3价格升序，4价格降序
        switch (sortType){
            case 0:
                page = spuService.frontfindPage(new Page<>(pageNum, pageSize),spuDto);
                break;
            case 1:
                page = spuService.frontfindPageBySalesAsc(new Page<>(pageNum, pageSize),spuDto);
                break;
            case 2:
                page = spuService.frontfindPageBySalesDesc(new Page<>(pageNum, pageSize),spuDto);
                break;
            case 3:
                page = spuService.frontfindPageByPriceAsc(new Page<>(pageNum, pageSize),spuDto);
                break;
            case 4:
                page = spuService.frontfindPageByPriceDesc(new Page<>(pageNum, pageSize),spuDto);
                break;
        }
        PageResult<SSpuVO> pageResult = PageResult
                .<SSpuVO>builder()
                .current(page.getCurrent())
                .size(page.getSize())
                .total(page.getTotal())
                .records(page.getRecords())
                .build();

        return Result.success(pageResult);

    }

    @ApiOperation("根据spuid获取spu")
    @GetMapping("/{id}")
    public Result<SSpuVO> getOneSpu(@PathVariable Long id){
        SSpuVO one = spuService.getOneSpuVO(id);
        return Result.success(one);

    }



}
